{
    title:  "Appweb Architecture",
    crumbs: [ 
        { 'Reference': '../ref/' },
    ],
}

            <h1>Appweb Architecture</h1><!--
    Diagrams:
        - Process diagram
        - Request pipeline
        - Module Block diagram
        - Key objects
-->
            <p>The Appweb HTTP web server is the fastest little web server. It is a high-performance yet compact
            embeddable webserver that has a modular, secure core.  It supports an extensive feature set including:
            HTTP/1.1, TLS/SSL, CGI, PHP, ESP, Virtual Hosts, Digest
            Authentication, Apache style configuration, and logging and security sandboxing. Yet Appweb remains very
            small (from 1MB) and exceptionally fast (&gt; 7,000 requests per second).</p>
            <p>Appweb supports dynamic web application frameworks like ESP, and PHP. It also supports older
            web creation strategies like CGI.</p>
            <p>Appweb is an event-driven, multi-threaded web server and is able to support many
            thousands of requests per second but it does not try to scale out like an enterprise class server for 
            top-tier web sites.
            Rather, it aims to be robust, secure and blazing fast with low and predictable memory utilization.</p>
            <a id="deployment"></a>
            <h2>Deployment Models</h2>
            <p>Appweb can be deployed in several ways:</p>
            <ul>
                <li>As a stand-alone web server</li>
                <li>Embedded in applications and devices</li>
                <li>Proxied behind front-end web servers</li>
            </ul>
            <h3>Stand-Alone Web Server</h3>
            <p>The Appweb distribution contains a robust, secure, stand-alone web server. The binary installation will
            install this web server to be automatically started as a system daemon/service. It is supervised by a
            manager process which acts as a guardian to start, monitor and restart Appweb if required.</p>
            <h3>Embedded in Applications and Devices</h3>
            <p>Appweb provides an embeddable server and client library so that any application can be web-enabled. When
            embedded, the application can provide data and respond to requests over HTTP. For devices, Appweb can be
            configured with the minimal required set of features for minimal memory and security footprint.</p>
            <h3>Proxied</h3>
            <p>Appweb is an ideal application web server when running behind a reverse proxy. The
            reverse proxy dispatches incoming requests to a set of Appweb instances which can effectively host
            ESP, or PHP applications.</p>
            
            <a id="processing"></a>
            <h2>Processing Architecture</h2>
            <p>Appweb typically runs one, multi-threaded, event driven process. Appweb uses a non-blocking
            event driven architecture and is capable of running many requests simultaneously.</p>
            <h3>Event Driven and Multi-threaded</h3>
            <p>While Appweb is multi-threaded, it does not consume a thread per request. A high performance thread pool
            is used to temporarily loan worker threads as required to service incoming requests. While waiting for
            incoming and outgoing I/O, the worker thread is returned to the pool for use by other requests. This
            architecture minimizes memory usage by reusing threads and provides excellent performance due to the thread
            pool. Further, it scales well, as one thread can service many requests.</p>
            
            <a id="modules"></a>
            <h2>Appweb Modules</h2>
            <p>Embeddable web servers have several competing goals:</p>
            <ul>
                <li>Minimize memory footprint</li>
                <li>Minimize CPU consumption</li>
                <li>Maximize security</li>
                <li>Provide a strong and standard feature set</li>
            </ul>
            <p>To meet all these goals in one server is difficult. Appweb uses loadable modules so that the core Appweb
            HTTP server may be compact, secure, and fast while still having the ability to grow functionality as
            required.</p>
            <p>An Appweb loadable module is a discrete unit of functionality that may be linked into Appweb to enhance
            the core HTTP server. A module may be a request handler, filter, network connector, or simply a "lump" of
            code.</p>
            <h3>Core Components</h3>
            <p>Appweb has a modular architecture where modules are dynamically loaded at runtime depending on the
            desired configuration. The key components of Appweb are:</p>
            <p><img src="../images/modules.jpg" alt="Appweb Architecture" /></p>
            <table title="Components" class="ui celled table segment">
                <thead>
                    <tr>
                        <th class="five wide">Component</th>
                        <th>Description</th>
                    </tr>
                </thead>
                <tbody>
                <tr>
                    <td>Multithreaded Portable Runtime</td>
                    <td>Cross-platform, multi-threaded portable runtime. Includes services for memory allocation,
                    dynamic module loading, safe string handling, lists, hashing, command execution, socket
                    communications, threads, thread synchronization, thread-pool, events, timers, debug trace and
                    logging.</td>
                </tr>
                <tr>
                    <td>Appweb HTTP Core Library</td>
                    <td>Core HTTP server. Includes services for initialization, HTTP protocol handling, socket
                    connection management, logging, virtual hosts, directory and location blocks, request processing
                    pipeline, and module loading and management.</td>
                </tr>
                <tr>
                    <td>File Handler</td>
                    <td>The File handler serves static content such as HTML pages, images and PDF files. It works
                    cooperatively with the Send connector to eliminate reading such content into memory. The File
                    handler sends details of the content name via the processing pipeline to the Send connector which
                    uses special O/S APIs to directly copy files to the network.</td>
                </tr>
                <tr>
                    <td>ESP Handler</td>
                    <td>The Embedded Server Pages (ESP) web framework is an advanced, Model,View,Controller "C" 
                        language web framework.</td>
                </tr>
<!-- KEEP
                <tr>
                    <td>Ejscript Handler</td>
                    <td>Ejscript Web Framework Handler. This is a Server-Side JavaScript web application framework.
                    Ideal for dynamic web applications.</td>
                </tr>
-->
                <tr>
                    <td>PHP Handler</td>
                    <td>In-memory handler module for the PHP web environment.</td>
                </tr>
                <tr>
                    <td>CGI Handler</td>
                    <td>Common Gateway Interface handler.</td>
                </tr>
                <tr>
                    <td>Chunk Filter</td>
                    <td>The Chunk applies Transfer Chunk Encoding to outgoing data. Chunk encoding enables the HTTP
                    connection to be reused for subsequent requests without having to establish a new TCP/IP
                    connection. This can significantly improve network and application performance.</td>
                </tr>
                <tr>
                    <td>Range Filter</td>
                    <td>The Range filter selects the requested I/O range by the client. The Range filter works
                    cooperatively with the File handler and Send connector to eliminate copying and reading static
                    content for ranged requests.</td>
                </tr>
                <tr>
                    <td>Net Connector</td>
                    <td>The Net connector is the general purpose transmitter of content to the client. It supports
                    vectored gather/scatter writes for optimal performance.</td>
                </tr>
                <tr>
                    <td>Send Connector</td>
                    <td>The Send connector is a special purpose transmitter of static file content to the client. It
                    uses operating system APIs to send file data to the client without reading the data into Appweb. It
                    also uses vectored gather/scatter I/O to blend response, chunk, and range headers into the static
                    data. These strategies dramatically boost the performance of serving static data.</td>
                </tr>
                <tr>
                    <td>Secure Sockets Layer (SSL)</td>
                    <td>Secure Socket Layer protocol stack. This is a virtual interface that can selectively support a
                    variety of SSL providers including: the MbedTLS and OpenSSL stacks.</td>
                </tr>
                </tbody>
            </table>
            
            <a id="httpServer"></a>
            <h3>Appweb HTTP Server Core</h3>
            <p>The core Appweb HTTP server is one of the relatively smaller components of the Appweb product when
            compared to the dynamic modules that run atop it. The core server provides a set of services for the
            handlers, filters and connectors to use when serving content to clients. The goal is to centralize any
            facilities for the modules so it will not be replicated.</p>
            <p>The core services include: the main HTTP processing and socket communications, initialization and
            parsing the Appweb configuration file, server, virtual host and directory authorization management, request
            pipeline management and request processing.</p>
            <p>The core server also configures and enforces any sandbox resource limits that have been requested in the
            configuration file, for example: thread limits and request URI and body size limitations. This enables
            Appweb to be deterministic in its use of system resources and to be a good system citizen. The core Appweb
            server can be configured to execute single or multi-threaded. With appropriate sandbox limits, it can serve
            thousands of requests per second if required.</p>
            
            <a id="configuration"></a>
            <h2>Appweb Configuration</h2>
            <p>Appweb uses an Apache style configuration file. This configuration file is read when Appweb starts and
            it manages every aspect of Appweb's configuration including what ports and addresses to listen to, what
            modules to load, where to find the web pages, and how to log requests.</p>
            <p>The configuration file supports a wide variety of directives such as virtual hosting, directory
            authentication, port binding, aliasing, logging, and request pipeline configuration. It has conditional
            declarations and supports the inclusion of other configuration files. Appweb uses a one-pass traversal of the
            configuration file which means that the order of directives matters.</p>
            
            <a id="requests"></a>
            <h2>Request Processing</h2>
            <p>The Appweb HTTP core manages the processing of requests and the construction of the request processing
            pipeline. When a new HTTP request arrives, Appweb will examine the network interface on which the request
            arrived, and if it is assigned to an IP based virtual host, Appweb will route the request to be handled by
            that virtual host. If name based virtual hosting is configured, the determination of which virtual host
            will process the request must be deferred until the HTTP header has been parsed and the default server is
            used to initially parse the request. See the <a href="../users/vhosts.html">Virtual
            Hosts</a> for more information.</p>
            <h3>HTTP Header Parsing</h3>
            <p>The first line of the HTTP request specifies the HTTP operation method to use, the URI to access and the
            variant of the HTTP protocol to use. This typically looks like:</p>
            <pre class="ui code segment">
<b>GET</b> /index.html HTTP/1.1
</pre>
            <p>This example is asking for the /index.html document via the GET method using the HTTP/1.1 protocol.</p>
            <p>After the request line, follow a set of HTTP headers. Typically there are 5-15 headers which specify
            further information to help the server process the request. Headers are of the format:</p>
            <pre class="ui code segment">
HeaderName: value
</pre>
            <p>Some typical headers are:</p>
            <table title="Headers" class="ui celled table segment">
                <thead>
                    <tr>
                        <th>Header</th>
                        <th>Description</th>
                    </tr>
                </thead>
                <tbody>
                <tr>
                    <td>Authorization</td>
                    <td>Authorization details including user name, realm, password digest and other authorization
                    parameters to implement Basic and Digest authentication.</td>
                </tr>
                <tr>
                    <td>Connection</td>
                    <td>Describe how the TCP/IP connection should be managed when the request completes.</td>
                </tr>
                <tr>
                    <td>Content-Length</td>
                    <td>Length of any addition data with a POST request.</td>
                </tr>
                <tr>
                    <td>Content-Type</td>
                    <td>Mime types the client prefers to accept in response to this request.</td>
                </tr>
                <tr>
                    <td>Cookie</td>
                    <td>Cookie associated with the URI in the clients cookie cache.</td>
                </tr>
                <tr>
                    <td>Host</td>
                    <td>Name to the target host to serve the request. This specifies the host name when using virtual
                    hosting.</td>
                </tr>
                <tr>
                    <td>If-Modified-Since</td>
                    <td>Only return the content if it has been modified since the date specified. Clients who have
                    cached copies of a document (or graphics) use this header to allow the server to skip copying the
                    document if it has not changed.</td>
                </tr>
                <tr>
                    <td>Keep-Alive</td>
                    <td>Request the server to keep the connection alive so that subsequent requests can reuse the
                    connection.</td>
                </tr>
                </tbody>
            </table>
            <p>For example:</p>
            <pre class="ui code segment">
Connection: keep-alive
</pre>
            <p>Appweb parses the HTTP headers and stores their values in a hash table for access by the request
            handlers and pipeline stages. When all the headers have been processed Appweb proceeds to do handler
            matching. This will occur before any associated POST data has been read from the client. POST data may be
            form data submitted by the client or it may be a file upload using the PUT method.</p>
            <h3>Request Routing</h3>
            <p>Appweb has a powerful request routing engine that processes client HTTP requests. The engine is 
            configured with a set of routes from the Appweb configuration file. When a request is received, 
            it tests various routes and selects 
            the best route to handle the request. In the process, routes may redirect or rewrite the request as required.</p>
            <p>An Appweb configuration will typically have many routes. The configured routes are tested in order 
            by matching the route regular expression pattern against the request URI. A route may require that 
            further preconditions 
            be met before it is suitable to process the request. If the required conditions are not met, the next 
            route in the configuration will be tested. There is always a catch-all route that will process the 
            request if all prior routes fail to qualify.</p>
            <p>To define a route, use the <a href=
            "../users/dir/route.html">Route</a> directive. For example:</p>
            <pre class="ui code segment">
&lt;Route /projects/video&gt;
    SetHandler videoHandler
&lt;/Route&gt;
</pre>
            <p>This will cause the videoHandler to respond to any URI that begins with "/projects/video" after the
            http://site portion of the URI.</p>
            <p>To associate a handler to a given extension, use the <a href=
            "../users/dir/route.html#addHandler">AddHandler</a> directive. For example:</p>
            <pre class="ui code segment">
AddHandler espHandler myDoc
</pre>
            <p>This will cause the ejsHandler to respond to any URI that has a "<em>.myDoc</em>" extension.</p>
            <p>Multiple routes may match a URI. In this case they are applied in the order they are specified in the
            Appweb configuration file. 
            <p>Once the route has been selected, the request pipeline is constructed and the request handler is started
            to create the response for the client.</p>
            
            <a id="pipeline"></a>
            <h2>Request Pipeline</h2>
            <p>The Appweb core uses a bidirectional pipeline to process requests and generate responses. This consists
            of a mechanism of queues, packets, buffering and event scheduling. The pipeline architecture is highly
            optimized and supports the efficient transmission of data without copying. It uses vectored, scatter/gather
            writes to the network to avoid the costly aggregation of data and headers in a single buffer before writing
            to the network.</p>
            <h3>Pipeline Stages</h3>
            <p>The request pipeline is comprised of an incoming and outgoing stream. Each stream is in turn comprised
            of <b>stages</b>. Each stage has a data queue with two service routines, one to accept data without queuing
            and one for delayed servicing of previously queued data. Pipeline stages support flow-control and can queue
            data for delayed servicing if the downstream stage cannot currently accept data.</p><img src=
            "../images/pipeline.jpg" alt="pipeline" />
            <p>A typical pipeline consists of the following <b>stages</b>.</p>
            <ul>
                <li>One handler</li>
                <li>Zero or more filters</li>
                <li>One network connector</li>
            </ul>
            <h3>Http Core</h3>
            <p>The Appweb HTTP core is responsible for parsing the incoming HTTP request. The HTTP request first line
            specifies the request URI resource and the request headers provide additional context. The HTTP core stores
            the parsed headers for use by the routing engine and creates a new request pipeline to process the request.
            The incoming and outgoing pipelines are constructed separately as each direction may require a different set
            of filters.</p>
            
            <h3>Routing Engine</h3>
            <p>The routing engine matches the request against the configured request routes and selects the best 
            route for the request. A route specifies the handler to manage the request and other context such as where
            to find documents to serve. The routing engine may rewrite the request and then reroute. The engine 
            also manages HTTP authorization.</p>
            <p>Depending on the request URI and headers, the appropriate handler will be selected.  There are handlers
            for ESP, PHP, CGI and static file data.</p>
            <h3>Handlers</h3>
            <p>The handler is responsible for receiving the request and creating a response. It generates response
            content based on the HTTP request URI, headers, any associated body data, and potential application session
            state. The output data flows through the output pipeline before transmission by the network connector to
            the client.</p>
            <p>There is one handler for each request. The Appweb core selects that handler based on a request matching
            algorithm. Handlers are configured in the Appweb configure file via the <a href=
            "../users/dir/route.html#addHandler">AddHandler</a> and the <a href=
            "../users/dir/route.html#setHandler">SetHandler</a> directives.</p>
            <h3>Filters</h3>
            <p>The filters job is to permute the data in some way and pass it on to the next stage in the pipeline.
            Filters connect one to another and multiple filters may be used in both the incoming and outgoing pipeline
            directions.</p>
            <p>The order of filters typically does matter. For example, compressing data before encrypting is not the
            same as encrypting then compressing. Appweb provides the <a href=
            "../users/dir/route.html#addInputFilter">AddInputFilter</a> and <a href=
            "../users/dir/route.html#addOutputFilter">AddOutputFilter</a> directives to assist in
            constructing filter pipelines.</p>
            <p>Appweb uses filters to implement Transfer Authorization, Chunk Encoding and HTTP Ranged requests. By
            using filters to implement these features, they automatically become available to all handlers and all
            content types.</p>
            <h3>Connectors</h3>
            <p>The connector is responsible for transmitting the outgoing data to the client. It receives a set of
            packets representing the data to send to the client. The connector is responsible for requesting the Appweb
            HTTP core to create a packet with the HTTP response headers. It is at this stage that Appweb can determine
            if the TCP/IP connection can be kept alive for subsequent requests on the same connection.</p>
            <h4>Delayed Headers</h4>
            <p>Connectors will receive an empty header packet which must first be filled with the HTTP response
            headers. By delaying the generation of the HTTP headers until the last possible moment, Appweb maximizes
            every opportunity to optimize the response and use the HTTP/1.1 Keep-Alive feature even for dynamically
            generated data.</p>
            <h4>Send Connector</h4>
            <p>If the File handler is communicating directly to the Send connector, it will optimize its operation by
            not reading the static file data. Rather, it will send empty packets to the Send connector which will use
            the operating system <b>sendfile</b> (or equivalent) primitive. This avoids reading the static file data
            into the Appweb user process.</p>
            <h4>Net Connector</h4>
            <p>The Net connector is a generalized network connector that can transmit content from any handler to the
            client. It supports vectored writes to avoid copying data when interleaving with HTTP, range or chunk
            headers.</p>
            
            <a id="frameworks"></a>
            <h2>Web Frameworks</h2>
            <p>Appweb supports loadable modules for the ESP, and PHP web frameworks.</p>
            <h3>Embedded Server Pages  Web Framework</h3>
            <p>The ESP web framework is a high performance, Model/View/Controller web framework. 
            It uses the "C" language embedded in HTML web pages and for Controllers. It provides 
            an application generator, templating and layout engine, a Model/View/Controller framework, extensive caching,
            and a library of Ajax view controls. It is blazing fast via the use of "C" and caching of 
            compiled web pages and rendered HTML.
<!-- KEEP
            <h3>Ejscript Web Framework</h3>
            <p>The Ejscript Web Framework was designed to make it easier to create dynamic web applications. It uses
                server-side JavaScript as the application language and provides provides an application generator,
                templating engine, a powerful Model/View/Controller framework, and a library of Ajax view controls. See
                the <a href="ejsArchitecture.html">Ejscript Web Framework</a> for more details.</p>
-->
            <h3>PHP</h3>
            <p>PHP is a widely-used general-purpose scripting language that is especially suited for Web development
            and can be embedded into HTML. Appweb provides a fast, in-memory handler for the PHP web framework.</p>
            
            <a id="security"></a>
            <h2>Security</h2>
            <p>Appweb provides a suite of measures designed to increase the security of your web server:</p>
            <ul>
                <li>Secure Sockets Layer</li>
                <li>Authorization directives</li>
                <li>Sandbox directives</li>
                <li>MPR &mdash; secure portable runtime</li>
                <li>Manager monitoring process</li>
            </ul>
            <h4>Secure Sockets</h4>
            <p>Appweb supports the MbedTLS and OpenSSL stacks. You can configure server and/or client
            certificate-based authentication. SSL and TLS are supported.</p>
            <h4>Authentication</h4>Appweb provides the Digest authentication mechanism and supports both file and
            PAM-based authentication backends.
            <h4>Sandboxing</h4>
            <p>Sandboxing is the term applied to running Appweb in a confined environment. Appweb has a set of
            configuration file directives that allow you to define a sandbox which limits the resources that Appweb may
            used for a given request. By using well defined sandbox directives, you can help ensure that your
            application and system will not be compromised by malicious requests.</p>
            
            <a id="mpr"></a>
            <h2>Multithreaded Portable Runtime (MPR)</h2>
            <p>Appweb is built upon a portable runtime layer called the MPR. This layer insulates the rest of the
            product from the underlying platform and allows it to be highly portable to new operating systems or
            hardware.</p>
            <p>The MPR provides a suite of services that facilitate the creation of high performance,
            multi-threaded management and server applications, including: thread management, dynamic module loading, 
            networking, safe string handling, timers, XML parsing and logging.</p>
            <p>The MPR also provides a safer environment in which to program as it replaces 'C' APIs that are prone to
            buffer overflows and other similar security exploits. The MPR includes a high performance, safe string
            library that supports a secure programming style.</p>
            <p>The MPR event processing mechanism can be easily integrated into existing applications. It supports
            single and multi-threaded architectures, polled or async event notification, POSIX select waiting and
            Windows message loops. When coupled with C and C++ APIs, API web can be easily integrated into most C/C++
            applications.</p>
            <p>The MPR includes a high performance memory allocator and generational garbage collector. 
            The allocator is a fast, coalescing allocator that exhibits very low fragmentation.  It is optimized 
            for frequent allocations of small blocks and uses a background collector for freeing unused memory.</p>
            <p>The garbage collector is somewhat unusual in a C program. However, garbage collection is 
            especially well suited for long running applications like a web server as it virtually eliminates 
            memory leaks. Unlike traditional memory allocation where free must be called, Appweb 4 uses the 
            opposite approach where memory that must be retained, needs to be actively managed to prevent 
            garbage collection. This means that a managed reference must be held for all active memory. 
            See <a href="memory.html">Memory Allocation</a> for more details.</p>
            <a id="misc"></a>
            <h2>Misc Features</h2>
            <h3>IP Networking</h3>
            <p>Appweb fully supports both IPv4 and IPv6 for both server and client operations. You can configure Appweb
            to listen on both IPv4 and IPv6 addresses.</p>
            <h2>Embedding APIs</h2>
            <p>The Appweb HTTP server library can be embedded in an application to web-enable that application. 
            Appweb provides two levels of embedding:</p>
            <h3>One Line Embedding</h3>
            <p>Appweb can be embedded in one C statement. This will create a web server instance based on the given
            configuration file.:</p>
            <pre class="ui code segment">
maRunWebServer("appweb.conf");
</pre>
            <h3>Expanded Control</h3>
            <p>Appweb also provides a detailed API so you can create an embedded web server instance and control
            virtual hosts, port binding, directory and location blocks and every other part of Appweb. See the <a href=
            "api/appweb.html">Appweb Native API</a> for full details.</p>
